package com.pic.others.service.impl;

import cn.hutool.json.JSONUtil;
import com.pic.common.autoconfigure.mq.RabbitMqHelper;
import com.pic.common.constants.MqConstants;
import com.pic.common.utils.R;
import com.pic.common.utils.UserContext;
import com.pic.others.config.minio.MinIOConfigProperties;
import com.pic.others.config.minio.MinIOUtil;
import com.pic.others.domain.po.Note;
import com.pic.others.domain.po.Picture;
import com.pic.others.domain.vo.note.NotePictureVO;
import com.pic.others.domain.vo.note.NoteWithContentVO;
import com.pic.others.mapper.NoteMapper;
import com.pic.others.service.INoteService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author koshi
 * @since 2023-11-24
 */
@RequiredArgsConstructor
@Slf4j
@Service

public class NoteServiceImpl extends ServiceImpl<NoteMapper, Note> implements INoteService {

    public final MinIOUtil minIOUtil;
    public final NoteMapper noteMapper;
    private final RabbitMqHelper mqHelper;
    private final  MinIOConfigProperties minIOConfigProperties;

    @Value("${minio.bucket}")
    String bucket;
    @Override
    public R<String> deleteByNoteId(long noteId) {
        log.info("noteId:{}",noteId);
        Note note=lambdaQuery().eq(Note::getNoteId,noteId).one();
        log.info("note:{}",note);
        List<String> stringList = JSONUtil.toList(note.getLocates(), String.class);
        for(String s:stringList){
           log.info("路径：{}",s);
        }
        //        boolean deletedFromMinIO = minIOUtil.deleteFile(bucketName, minIOConfigProperties.getReadPath() +vo.getLocate());
        for(String locate:stringList){
            log.info(minIOConfigProperties.getReadPath());
            log.info(locate);
            minIOUtil.deleteFile(bucket,minIOConfigProperties.getReadPath()+locate);
        }

        boolean flag = removeById(noteId);
        note=null;
        if(flag){
            return R.success("删除成功");
        }else
            return R.error("删除失败");
    }

    @Override
    public R<NotePictureVO> queryByNoteId(long noteId) {
        Note note = getById(noteId);
        String locates = note.getLocates();
        List<String> stringList = JSONUtil.toList(locates, String.class);
        NotePictureVO nvo=new NotePictureVO
                (noteId,note.getCreateTime(),note.getAddress(),note.getUserId(),note.getNoteContent(),
                        stringList );
        return R.success(nvo);
    }

    @Override
    public R<String> updateNote(Note note, List<MultipartFile> pictures) {
        List<String>locates=new ArrayList<>();
        String noteLocates = note.getLocates();
        List<String> stringList = JSONUtil.toList(noteLocates, String.class);
       //使用rabbitmq
        mqHelper.send(
                MqConstants.Exchange.NOTE_EXCHANGE,
                MqConstants.Key.NOTE_DELETE_KEY,
                stringList
        );
        for(MultipartFile multipartFile:pictures){
            String s = minIOUtil.uploadImgFile(bucket, String.valueOf(note.getUserId()),
                    multipartFile, multipartFile.getName());
            locates.add(s);
        }
        String json = JSONUtil.toJsonStr(locates);
        note.setLocates(json);
        boolean flag = updateById(note);
        if(flag){
            return R.success("更新成功");
        }else{
            return R.error("更新失败");
        }
    }

    @Override
    public R<String> addNote(Note note, MultipartFile picture) {
        note.setUserId(UserContext.getUser());
        note.setCreateTime(LocalDate.now());
        List<String>list=new ArrayList<>();
            String s = minIOUtil.uploadImgFile(bucket, String.valueOf(UserContext.getUser()),
                    picture, picture.getName());
            list.add(s);
        String locates = JSONUtil.toJsonStr(list);
        note.setLocates(locates);
        long insert = (long)noteMapper.insert(note);
       return R.success("插入成功");
    }

    @Override
    public R<List<Picture>> getPictureByMaybeNeed(String content) {
        return null;
    }

    @Override
    public R<List<NotePictureVO>> getAllNoteByUserId() {
        long userId = UserContext.getUser();
        List<Note> notes = lambdaQuery().eq(Note::getUserId, userId).list();
        List<NotePictureVO>vos=new ArrayList<>();
        for(Note note:notes){
            NotePictureVO vo=new NotePictureVO();

            String locatesString = note.getLocates();
            log.info("locatesString: {}", locatesString);

            List<String> locates = JSONUtil.toList(locatesString, String.class);

            vo.setLocates(locates);
            vo.setAddress(note.getAddress());
            vo.setCreateTime(note.getCreateTime());
            vo.setNoteContent(note.getNoteContent());
            vo.setNoteId(note.getNoteId());
            vo.setUserId(note.getNoteId());

            vos.add(vo);
        }
        return R.success(vos);

    }

    @Override
    public R<Map<LocalDate, List<NotePictureVO>>> getAllNoteByUserInGroup() {
        long userId=UserContext.getUser();
        List<Note> list = lambdaQuery().eq(Note::getUserId, userId).list();
        Map<LocalDate,List<NotePictureVO>>notes=new HashMap<LocalDate, List<NotePictureVO>>();
        for(Note note:list){
            NotePictureVO notePictureVO=new NotePictureVO(note.getNoteId(),
                    note.getCreateTime(),note.getAddress(),userId,note.getNoteContent(),
                    JSONUtil.toBean(note.getLocates(), List.class));
           notes.putIfAbsent(note.getCreateTime(),new ArrayList<NotePictureVO>());
           notes.get(note.getCreateTime()).add(notePictureVO);
        }
        return R.success(notes);

    }

    @Override
    public R<String> addNoteByContent(@RequestBody NoteWithContentVO vo) {
        Note note=new Note();
        note.setUserId(UserContext.getUser());
        note.setCreateTime(LocalDate.now());
        note.setNoteContent(vo.getContent());
        note.setAddress(vo.getAddress());
        Long insert = Long.valueOf(noteMapper.insert(note));
        log.info("insert:{}",insert);
        log.info(note.toString());
        log.info(note.getNoteId().toString());
        return R.success(note.getNoteId().toString());
    }

    @Override
    public R<String> addNoteByPicture(Long noteId, MultipartFile file) {
        log.info("你进来了");

        if (file == null || file.getSize() == 0) {
            return R.success("成功");
        }

        Long userId = UserContext.getUser();
        log.info("userId:{}", userId);

        synchronized (this) {
            // 在同步块内进行读取和更新操作
            Note note = getById(noteId);
            log.info("note:{}", note);
            log.info("file.getName()：{}", file.getOriginalFilename());
            log.info("file；{}", file);
            log.info(note.toString());

            List<String> locates = JSONUtil.toList(note.getLocates(), String.class);

            String prefix = String.valueOf(userId);
            String locate = minIOUtil.uploadImgFile(bucket, prefix, file, null);
            log.info("上传图片到Minio中，图片路径是{}", locate);
            locates.add(locate);

            // 将 List<String> 转为 JSON 数组字符串
            note.setLocates(JSONUtil.toJsonStr(locates));

            updateById(note);
        }

        return R.success("上传成功");
    }


    @Override
    public R<String> updateContent(Note note) {
        Note oldNote = getById(note.getNoteId());
        oldNote.setNoteContent(note.getNoteContent());
        oldNote.setAddress(note.getAddress());
        boolean flag = updateById(oldNote);
        if(flag){
            return R.success(note.getNoteId().toString());
        }
        return R.error("出现问题，请联系管理员");
    }
}
